package com.nit.lab.service.basic.impl;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.nit.lab.dto.basic.UserDTO;
import com.nit.lab.dto.utils.PagingDTO;
import com.nit.lab.dto.utils.TableReqDTO;
import com.nit.lab.dto.utils.TableRspDTO;
import com.nit.lab.entity.basic.UserEntity;
import com.nit.lab.mapper.basic.UserMapper;
import com.nit.lab.service.basic.UserService;
import com.nit.lab.utils.MyX509TrustManager;
import io.lettuce.core.ScriptOutputType;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.*;
import java.net.ConnectException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;

@Service
@EnableScheduling
public class UserServiceImpl implements UserService {

    @Autowired(required = false)
    private UserMapper userMapper;

    @Override
    public TableRspDTO list4Table(TableReqDTO tableReqDTO) throws Exception {
        Long count = userMapper.count4Table(
                tableReqDTO.parseQueryParam("loginName"),
                tableReqDTO.parseQueryParam("userName"),
                tableReqDTO.parseQueryParam("roleId"));
//                tableReqDTO.parseQueryParam("unitId"));
        PagingDTO pagingDTO = new PagingDTO(
                tableReqDTO.getPageNo(),
                tableReqDTO.getPageSize(),
                count,
                userMapper.list4Table(
                        tableReqDTO.getStart(),
                        tableReqDTO.getPageSize(),
                        tableReqDTO.parseQueryParam("loginName"),
                        tableReqDTO.parseQueryParam("userName"),
                        tableReqDTO.parseQueryParam("roleId"),
//                        tableReqDTO.parseQueryParam("unitId"),
                        tableReqDTO.getSortField(),
                        tableReqDTO.getSortOrder()));
        TableRspDTO tableRspDTO = new TableRspDTO(pagingDTO);
        return tableRspDTO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer add(UserDTO userDTO) throws Exception {
        MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
        UserEntity userEntity = mapperFactory.getMapperFacade().map(userDTO, UserEntity.class);
        //userEntity.setUserImage("soldier.png");
        userEntity.setLoginPwd(DigestUtils.md5DigestAsHex(userDTO.getLoginPwd().getBytes(StandardCharsets.UTF_8)));
        userEntity.setGmtCreate(new Date());
        userEntity.setGmtModified(new Date());
        return userMapper.add(userEntity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer update(UserDTO userDTO) throws Exception {
        MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
        UserEntity userEntity = mapperFactory.getMapperFacade().map(userDTO, UserEntity.class);
        userEntity.setGmtModified(new Date());
        return userMapper.update(userEntity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer remove(String userIds) throws Exception {
        String[] arrayUserId = userIds.split(",");
        for (int i = 0; i < arrayUserId.length; i++) {
            userMapper.remove(Long.parseLong(arrayUserId[i]));
        }
        return arrayUserId.length;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer resetPwd(Long userId, String loginPwd) throws Exception {
        return userMapper.resetPwd(userId, DigestUtils.md5DigestAsHex(loginPwd.getBytes()));
    }

    @Override
    public UserDTO loginCheck(String loginName) throws Exception {
        return userMapper.getByLoginName(loginName);
    }

    @Override
    public UserDTO getByUserId(Long userId) throws Exception {
        return userMapper.getByUserId(userId);
    }

    @Override
    public UserDTO getByUserName(String userName) throws Exception {
        return null;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer updateUserType(Long userId) throws Exception {
        return userMapper.updateUserType(userId);
    }

    @Override
    public List<UserDTO> getUserListAll() throws Exception {
        return userMapper.getUserListAll();
    }

    @Override
    public  JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) throws Exception {
        JSONObject jsonObject = null;
        StringBuffer buffer = new StringBuffer();
        try {
            // 创建SSLContext对象，并使用我们制定的信任管理器初始化
            TrustManager[] ttm = {new MyX509TrustManager()};
            SSLContext sslContent = SSLContext.getInstance("SSL", "SunJSSE");
            sslContent.init(null, ttm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContent.getSocketFactory();

            URL url = new URL(requestUrl);
            HttpsURLConnection httpsUrlConn = (HttpsURLConnection) url
                    .openConnection();
            httpsUrlConn.setSSLSocketFactory(ssf);

            httpsUrlConn.setDoOutput(true);
            httpsUrlConn.setDoInput(true);
            httpsUrlConn.setUseCaches(false);
            // 设置请求方式(GET/POST)
            httpsUrlConn.setRequestMethod(requestMethod);
            if ("GET".equalsIgnoreCase(requestMethod)) {
                httpsUrlConn.connect();
            }
            // 当有数据需要提交时
            if (null != outputStr) {
                OutputStream outputStream = httpsUrlConn.getOutputStream();
                // 编码格式
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }

            // 将返回的输入流转换成字符串
            InputStream inputStream = httpsUrlConn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(
                    inputStream, "UTF-8");
            BufferedReader bufferedReader = new BufferedReader(
                    inputStreamReader);

            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            // 释放资源
            bufferedReader.close();
            inputStreamReader.close();
            httpsUrlConn.disconnect();
            System.out.println(buffer.toString());

            jsonObject = JSONObject.parseObject(buffer.toString());
        } catch (ConnectException e) {
            e.printStackTrace();
        }
        return jsonObject;
    }

    @Override
    public String sendPostJson(String url, String json) throws IOException {
        HttpPost httpPost = new HttpPost(url);
        StringEntity postEntity = new StringEntity(json, "UTF-8");
        httpPost.addHeader("Content-Type", "application/json");
        httpPost.setEntity(postEntity);
        //设置请求器的配置
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(30000).setConnectTimeout(10000).build();
        httpPost.setConfig(requestConfig);

        HttpClient httpClient = HttpClients.createDefault();
        HttpResponse response = httpClient.execute(httpPost);
        HttpEntity entity = response.getEntity();
        String result = EntityUtils.toString(entity, "UTF-8");
        return result;
    }


    public JSONObject getOpenId(String code) throws Exception {
        System.out.println(code);
        String appid = "wx30464d9c88eb8661";
        String appSecret = "df57240451fff2fc1c0a487d9b652f51";
        String url = "https://api.weixin.qq.com/sns/jscode2session?" + "appid=" + appid + "&secret=" + appSecret + "&js_code=" + code + "&grant_type=authorization_code";
        JSONObject result = httpsRequest(url, "GET", null);
        String openId = (String) result.get("openid");
        List<UserDTO> list = userMapper.getByOpenId(openId);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("openid",openId);
        System.out.println("openId");
        System.out.println(openId);
        if(list.size()!=0)
        {
            jsonObject.put("user",list.get(0));
            jsonObject.put("ans",1);
        }
        else{
            jsonObject.put("ans",0);
        }
        return jsonObject;
    }


    public  String getPhone(String code) throws  Exception{
//        String appid = "wx30464d9c88eb8661";
//        String appSecret = "df57240451fff2fc1c0a487d9b652f51";
//        String token_url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",appid,appSecret);
        String token_url = userMapper.getweixinToken();
        JSONObject accessToken = JSON.parseObject(HttpUtil.get(token_url));
        String token = (String) accessToken.get("access_token");
        System.out.println(accessToken);
        System.out.println(token);
        String urlPhone = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?" + "access_token=" + token;
        JSONObject res = new JSONObject();
        res.put("code",code);
        String phone = sendPostJson(urlPhone, String.valueOf(res));
        return phone;
    }



    public JSONObject weiAdd(JSONObject weiuser) throws Exception {
        UserEntity weiEntity = new UserEntity((String) weiuser.get("loginName"), (String) weiuser.get("loginPwd"), 2L, (String) weiuser.get("userName"), 1L, (String) weiuser.get("userInfo"), (String) weiuser.get("publicKey"), (String) weiuser.get("privateKey"), (String) weiuser.get("openId"), (String) weiuser.get("userUnit"));
        weiEntity.setLoginPwd(DigestUtils.md5DigestAsHex(weiEntity.getLoginPwd().getBytes(StandardCharsets.UTF_8)));
        weiEntity.setGmtCreate(new Date());
        weiEntity.setGmtModified(new Date());
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("user",weiEntity);
        userMapper.weiAdd(weiEntity);
        return jsonObject;
    }


    @Override
    @Scheduled(cron = "0 0 0/1 * * *")//每隔一小时执行一次
    public void setTokenByTime() throws Exception {
        String appid = "wx30464d9c88eb8661";
        String appSecret = "df57240451fff2fc1c0a487d9b652f51";
        String token_url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",appid,appSecret);
        userMapper.setTokenByTime(token_url);
    }


    @Override
    public String getweixinToken() throws Exception {
        return userMapper.getweixinToken();
    }

    @Override
    public String checkAdmiss(String checkAdmiss) throws Exception {
        return userMapper.checkAdmiss(checkAdmiss);
    }

    @Override
    public String getCheckName(String checkAdmiss) throws Exception {
        return userMapper.getCheckName(checkAdmiss);
    }

    @Override
    public String getCheckUnit(String checkAdmiss) throws Exception {
        return userMapper.getCheckUnit(checkAdmiss);
    }

    @Override
    public JSONObject getCheckAddress(String address) throws Exception {
        return userMapper.getCheckAddress(address);
    }

}
